/*
    Create a backup file XXX.YYY~ from XXX.YYY

    Contact info:
    bhepple@freeshell.org
    http://bhepple.freeshell.org

    Copyright (C) 1999-2008 Bob Hepple

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; see the file COPYING.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.

*/

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include "mylib.h"
#include "backup.h"

#ifdef SM_TURBOC
#define MAXPATHLEN 128
#define MAXNAMELEN 12
#endif

#ifdef SM_XENIX
#define MAXPATHLEN 255
#define MAXNAMELEN 14
#endif
 
#ifdef SM_SUNOS
#define MAXPATHLEN 1023
#define MAXNAMELEN 255
#endif
 
#ifdef SM_SYSV
#define MAXPATHLEN 1023
#define MAXNAMELEN 255
#endif

#ifdef linux
#include <sys/vfs.h>
#endif

#ifdef SM_XENIX /* no rename(2) on XENIX */
int rename ARG2(char *, oldname, char *, newname)
{
    if (link(oldname, newname) < 0)
	return(-1);
    return(unlink(oldname));
}
#endif

void static create_backup_filename ARG3(char *, backup, char *, filename, int, dosflag)
{
    char	*p, *ext;

    strcpy(backup, filename);

#ifdef SM_TURBOC
    while (p = strchr(backup, '\\'))
	*p = '/';
#endif

    /* Trim the filename to any system limit (e.g. 14 chars on XENIX) */
    p = strrchr(backup, '/');
    if (p == NULL)
	p = backup;
    else
	p++;
    if (strlen(p) > MAXNAMELEN)
	p[MAXNAMELEN] = 0;

    /* Dream up a backup filename */
    p = strrchr(backup, '/');
    if (p == NULL)
	p = backup;
    else
	p++;

    if (dosflag) { /* xxx.ext => xxx.~ex */
	ext = strchr(p, '.');
	if (ext == NULL)
	    strcat(p, ".~");
	else {
	    ext++;
	    ext[2] = ext[1];
	    ext[1] = ext[0];
	    ext[0] = '~';
	}
    } else { /* xxx.ext => xxx.ex~ */
	if (strlen(p) >= MAXNAMELEN) {
	    p[MAXNAMELEN - 1] = '~';
	    p[MAXNAMELEN] = 0;
	} else /* xxx.ext => xxx.ext~ */
	    strcat(backup, "~");
    }
}

/* Rename a file as a backup file */
int backup_file(filename)
    char	*filename;
{
    FILE	*file;
    char	backup[MAXPATHLEN + 1];

    if ((file = fopen(filename, "r")) != NULL) {
	fclose(file);

#ifdef SM_TURBOC
	create_backup_filename(backup, filename, 1);
#else
#ifdef linux
#define MSDOS_SUPER_MAGIC     0x4d44
	{
	    struct statfs statfsbuf;

	    statfs(filename, &statfsbuf);
	    if (statfsbuf.f_type == MSDOS_SUPER_MAGIC)
		create_backup_filename(backup, filename, 1);
	    else
		create_backup_filename(backup, filename, 0);
	}
#else
	create_backup_filename(backup, filename, 0);
#endif
#endif /* !SM_TURBOC */

	/* Unlink any previous backup file */
	unlink(backup);

	if (rename(filename, backup) < 0) {
	    fprintf(stderr, "Can't rename(%s, %s) errno=%d %s\n", filename, backup, errno, strerror(errno));
	    return(-1);
	}
    }
    return(0);
}

/* For emacs:
 * Local Variables:
 * tab-width: 8
 * End:
 */
